package com.example.word2pdf.core;

import fr.opensagres.poi.xwpf.converter.pdf.PdfConverter;
import fr.opensagres.poi.xwpf.converter.pdf.PdfOptions;
import org.apache.poi.ooxml.POIXMLDocument;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component
public class WordUtils {
    /**
     * this is the font name
     */
    private static final String FONT_NAME = "STSong-Light";

    /**
     * this is the font encoding
     */
    private final static  String FONT_ENCODE = "UniGB-UCS2-H";

    public static void searchAndReplace(String srcPath, String destPath, Map<String, String> map) {
        try {
            //read file from src path
            XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(srcPath));
            // replace paragraph context
            Iterator<XWPFParagraph> itPara = document.getParagraphsIterator();
            while (itPara.hasNext()) {
                XWPFParagraph paragraph = itPara.next();
                Set<String> set = map.keySet();
                for (String key : set) {
                    String paragraphText = paragraph.getText();
                    Matcher matcher = matcher(paragraphText, key);
                    if (matcher.find()) {
                        String x = matcher.replaceAll(map.get(key));
                        while (paragraph.getRuns().size() > 0) {
                            paragraph.removeRun(0);
                        }
                        paragraph.createRun().setText(x, 0);
                    }
                }
            }

            //replace all context in tables
            Iterator<XWPFTable> itTable = document.getTablesIterator();
            while (itTable.hasNext()) {
                XWPFTable table = itTable.next();
                int count = table.getNumberOfRows();
                for (int i = 0; i < count; i++) {
                    XWPFTableRow row = table.getRow(i);
                    List<XWPFTableCell> cells = row.getTableCells();
                    for (XWPFTableCell cell : cells) {
                        for (XWPFParagraph p : cell.getParagraphs()) {
                            Set<String> set = map.keySet();
                            for (String key : set) {
                                String paragraphText = p.getText();
                                Matcher matcher = matcher(paragraphText, key);
                                if (matcher.find()) {
                                    String x = matcher.replaceAll(map.get(key));
                                    while (p.getRuns().size() > 0) {
                                        p.removeRun(0);
                                    }
                                    p.createRun().setText(x, 0);
                                }
                            }
                        }
                    }
                }
            }

            //word 转 pdf
            setFontType(document);
            docxToPdf(document, destPath);
            document.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 正则匹配字符串  正则匹配规则
     * reg : \$\{(%s)\}
     * @param str st
     * @return Matcher
     */
    private static Matcher matcher(String str, String pattern) {
        String format = String.format("\\$\\{(%s)\\}", pattern);
        Pattern r = Pattern.compile(format);
        return r.matcher(str);
    }

    /***
     * 将文档的文字设置为宋体 防止其他字体转pdf不显示
     * @param xwpfDocument document
     */
    private static void setFontType(XWPFDocument xwpfDocument) {
        //转换文档中文字字体
        List<XWPFParagraph> paragraphs = xwpfDocument.getParagraphs();
        if (paragraphs != null && paragraphs.size() > 0) {
            for (XWPFParagraph paragraph : paragraphs) {
                List<XWPFRun> runs = paragraph.getRuns();
                if (runs != null && runs.size() > 0) {
                    for (XWPFRun run : runs) {
                        run.setFontFamily(FONT_NAME);
                    }
                }
            }
        }
        //转换表格里的字体 我也不想俄罗斯套娃但是不套真不能设置字体
        List<XWPFTable> tables = xwpfDocument.getTables();
        for (XWPFTable table : tables) {
            List<XWPFTableRow> rows = table.getRows();
            for (XWPFTableRow row : rows) {
                List<XWPFTableCell> tableCells = row.getTableCells();
                for (XWPFTableCell tableCell : tableCells) {
                    List<XWPFParagraph> paragraphs1 = tableCell.getParagraphs();
                    for (XWPFParagraph xwpfParagraph : paragraphs1) {
                        List<XWPFRun> runs = xwpfParagraph.getRuns();
                        for (XWPFRun run : runs) {
                            run.setFontFamily(FONT_NAME);
                        }
                    }
                }
            }
        }
    }

    /**
     * word to pdf
     * @param document document
     * @param outUrl output url
     * @throws Exception e
     */
    private static void docxToPdf(XWPFDocument document, String outUrl) throws Exception {
        OutputStream outStream = getOutFileStream(outUrl);
        PdfOptions options = PdfOptions.create().fontEncoding(FONT_ENCODE);
        PdfConverter.getInstance().convert(document, outStream, options);
        System.out.println(22222);
        outStream.close();
    }

    /**
     * get out stream
     * @param outputFilePath out
     * @throws IOException io
     */
    private static OutputStream getOutFileStream(String outputFilePath) throws IOException {
        File outFile = new File(outputFilePath);
        return new FileOutputStream(outFile);
    }
}